using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;

using GURUCORE.Lib.Core.Text;


namespace GURUCORE.Lib.Core
{   
    /// <summary>
    /// Popular File processing util implement by GURUCORE.
    /// </summary>
    public static class File
    { 
        /// <summary>
        /// Thachnn: 20/12/2005
        /// Determine is input filename is temp file
        /// temp file is something like: Dynamic20051214010203.dll or Excel20051214010203.xls
        /// </summary>
        /// <param name="pstrFile"></param>
        /// <returns></returns>
        private static bool IsTempFile(string pstrFile)
        {
            /// this pattern mean:
            /// FileName is "xyz some thing", but must have at least one character
            /// Token must be 14 digits
            /// Dot is . sign
            /// Extension is dll or xls
            string strPattern = @"(?<FileNameGR>(\w+))(?<TokenGR>(\d+){14})(?<DotGR>\.)(?<ExtensionGR>(dll)|(xls))";
            return System.Text.RegularExpressions.Regex.Match(pstrFile, strPattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase).Success;
        }


        /// <summary>
        /// Thachnn : 25/Sep/2005
        /// Create a new tempfile in the Windows-local user temporary folder
        /// </summary>
        /// <returns>string contain filename of the new temporary file</returns>
        public static string GetTempFileName()
        {
            return System.IO.Path.GetTempFileName();
        }


        public static string GetTempFileNameGUID(string p_sOriginalFileName)
        {            
            string sFileExtension = System.IO.Path.GetExtension(p_sOriginalFileName);
            string sRet = Guid.NewGuid().ToString().Replace("-", string.Empty) + sFileExtension;
            return sRet;
        }
        


        /// <summary>
        /// 
        /// </summary>
        /// <param name="p_sStartingRootPath">RootPath to start inspect rescusive</param>
        /// <returns></returns>
        public static ArrayList RescursiveInspect(string p_sStartingRootPath)
        {
            ArrayList arrRet = new ArrayList();
            DirectoryInfo oRootDir = new DirectoryInfo(p_sStartingRootPath);


            FileInfo[] arrFile = oRootDir.GetFiles("*.*");

            foreach (FileInfo oFile in arrFile)
            {
                arrRet.Add(oFile.FullName);
            }

            DirectoryInfo[] arrSubDir = oRootDir.GetDirectories();
            foreach (DirectoryInfo oSubDir in arrSubDir)
            {
                arrRet.AddRange((RescursiveInspect(oSubDir.FullName)).ToArray());
            }

            return arrRet;
        }

        
        
        
        /// <summary>
        /// delete even readonly file. raise exception when error.
        /// </summary>
        /// <param name="p_sFileToDelete">FullPath + filename</param>
        /// <returns></returns>
        public static void StrongDeleteFile(string p_sFileToDelete)
        {            
            System.IO.File.SetAttributes(p_sFileToDelete, FileAttributes.Archive);
            System.IO.File.Delete(p_sFileToDelete);            
        }
                
        /// <summary>
        /// this function can delete even readonly file. set file to archive atrribute to delete. This function will not raise exception on error.
        /// </summary>
        /// <param name="p_sFileToDelete">FullPath + filename</param>
        /// <returns>false if fail for any exception, otherwise, return true if deleted ok</returns>
        public static bool StrongDeleteFileSafe(string p_sFileToDelete)
        {
            if (System.IO.File.Exists(p_sFileToDelete))
            {
                try
                {
                    System.IO.File.SetAttributes(p_sFileToDelete, FileAttributes.Archive);
                    System.IO.File.Delete(p_sFileToDelete);
                }
                catch { return false; } // file existed, exception raise, but can not delete, so return delete false
            }
            
            // file does not existed, so delete is completed without doing anything            
            return true;            
        }




        /// <summary>
        /// Read textfile till end, then close the reader. Use with care, use with small file only to save your memory.
        /// </summary>
        /// <param name="p_sFile"></param>
        /// <returns>null if error, string if read ok</returns>
        public static string ReadToEndOfTextFile(string p_sFile)
        {
            string sRet = string.Empty;
            if (string.IsNullOrEmpty(p_sFile) == false && System.IO.File.Exists(p_sFile))
            {
                System.IO.StreamReader StreamReader1 = null;
                try
                {
                    StreamReader1 = new System.IO.StreamReader(p_sFile);
                    sRet = StreamReader1.ReadToEnd();
                }
                catch { }
                finally
                {
                    if (null != StreamReader1)
                    { StreamReader1.Close(); }
                }
            }
            return sRet;
        }

        public static System.Xml.XmlDocument ReadXMLFileToXmlDocument(string p_sPath)
        {
            // read the XML file, return the XMLNode of profile
            XmlReaderSettings XRS = new XmlReaderSettings();
            XRS.CloseInput = true;
            XRS.IgnoreComments = true;
            XRS.IgnoreProcessingInstructions = true;
            XmlReader xReader = XmlReader.Create(p_sPath, XRS);
            XmlDocument xDoc = new XmlDocument();
            try
            {
                xDoc.Load(xReader);
            }
            catch //(Exception ex)
            {
                xReader.Close();
            }
            XmlElement xRoot = xDoc.DocumentElement;
            xReader.Close();
            return xDoc;
        }



        /// <summary>
        /// 
        /// </summary>
        /// <param name="p_dir">DirectoryInfo to start searching</param>
        /// <param name="p_sSearchPatternMulti">seperate extenstion by comma(,) .For example: *.exe,*.dll</param>
        /// <returns>Hashtable, key is fullname (with path), value is FileInfo</returns>
        public static Hashtable GetFiles(DirectoryInfo p_dir, string p_sSearchPatternMulti, SearchOption p_SearchOption, params char[] arrSplitDeliminator)
        {
            string[] arrExtension = p_sSearchPatternMulti.Split(arrSplitDeliminator);
            Hashtable htbRet = new Hashtable();

            foreach(string sExtension in arrExtension)
            {
                FileInfo[] arrFI = p_dir.GetFiles(sExtension, p_SearchOption);
                foreach (FileInfo fi in arrFI)
                {
                    htbRet.Add(fi.FullName, fi);
                }
            }

            return htbRet;
        }
        
    }   // end class
    
}   // end namespace
